﻿using System;
using System.IO;
using System.ServiceModel;
using Universe.IoC;
using Universe.WCF.Behaviors.WcfStreaming;

namespace WcfStreamTests
{
    [ServiceContract(SessionMode = SessionMode.NotAllowed)]
    public interface IMyService
    {
        [OperationContract]
        void Ping();

        [OperationContract]
        Stream GetMyStream(Guid token, int size, bool throwException);

        [OperationContract]
        long GetMyStreamLength(Guid token);

        [OperationContract]
        ResponseStatus GetMyStreamStatus(Guid token);
    }

    [ServiceBehaviorAttribute(
        IncludeExceptionDetailInFaults = false, 
        InstanceContextMode = InstanceContextMode.Single, 
        ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class MyService : IMyService
    {
        public const string MyExceptionMessage = "My Exception Message";
        public ConfigurationContainer Config = AdapterEnvironment.Default;
        
        public void Ping()
        {
        }

        public Stream GetMyStream(Guid token, int size, bool throwException)
        {
            BinaryWriterAdapter adapter = new BinaryWriterAdapter(token);
            adapter.Run(
                dataWriter =>
                {
                    GetMyStream_Impl(dataWriter, size, throwException);
                });


            return adapter.WcfResponseStream;
        }

        public long GetMyStreamLength(Guid token)
        {
            var storage = Config.ResolveRequired<IResponseStatusStorage>();
            ResponseStatus status;
            if (!storage.GetResponseStatus(token, out status))
                return -1;
            else
                return status.Length;
        }

        public ResponseStatus GetMyStreamStatus(Guid token)
        {
            var storage = Config.ResolveRequired<IResponseStatusStorage>();
            ResponseStatus status;
            if (storage.GetResponseStatus(token, out status))
            {
                storage.StoreResponseStatus(token, null);
                return status;
            }
            else
                return null;
        }

        void GetMyStream_Impl(BinaryWriter writer, int size, bool throwException)
        {
            if (throwException)
                throw new ArgumentException(MyExceptionMessage);

            for (int i = 0; i < size; i += 8)
            {


                writer.Write(1L);

                if (i == -9999)
                    throw new Exception();
            }

            // writer.Flush();
        }



    }
}
